package cn.wolfcode.luowowo.member.service.impl;

import cn.wolfcode.luowowo.cache.prefix.UserInfoKeyPrefix;
import cn.wolfcode.luowowo.cache.prefix.VerifyCodeKeyPrefix;
import cn.wolfcode.luowowo.cache.service.IUserInfoRedisService;
import cn.wolfcode.luowowo.cache.service.IVerifyCodeRedisService;
import cn.wolfcode.luowowo.common.Exception.VisiableException;
import cn.wolfcode.luowowo.member.domain.UserInfo;
import cn.wolfcode.luowowo.member.mapper.UserInfoMapper;
import cn.wolfcode.luowowo.common.util.AssertUtil;
import cn.wolfcode.luowowo.common.util.Cons;
import cn.wolfcode.luowowo.member.service.IUserInfoService;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StreamUtils;

import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.List;
import java.util.UUID;

@Service
public class UserInfoServiceImpl implements IUserInfoService {
    @Autowired
    private UserInfoMapper userInfoMapper;
    //注入验证码的保存的服务，不同模块的引入使用@Autowired，不同服务的引用使用@Reference
    @Reference
    private IVerifyCodeRedisService verifyCodeRedisService;
    @Reference
    private IUserInfoRedisService userInfoRedisService;

    public UserInfo get(Long id) {
        return userInfoMapper.selectByPrimaryKey(id);
    }
    //检查用户的手机是否存在
    public Boolean checkPhone(String phone) {
        return userInfoMapper.selectByPhone(phone) > 0;
    }
    //用户信息进行注册
    public void register(String phone, String nickname, String password, String rpassword, String verifyCode) {

        //判断传入的数据是否为null
        AssertUtil.haslength(phone,"手机号不能为空");
        AssertUtil.haslength(nickname,"昵称不能为空");
        AssertUtil.haslength(password,"密码不能为空");
        AssertUtil.haslength(rpassword,"确认密码不能为空");
        AssertUtil.haslength(verifyCode,"验证码不能为空");
        //判断两次输入的密码是否一致
        AssertUtil.isEqual(password,rpassword,"密码前后不一致");

        //判断手机号是否唯一
        if(this.checkPhone(phone)){
            throw new VisiableException("该手机号已经被注册");
        }

        //判断短信验证码是否一致 todo
        String code = verifyCodeRedisService.getVerifyCode(VerifyCodeKeyPrefix.VERIFY_CODE_KEY_PREFIX, phone);
        if(!code.equalsIgnoreCase(verifyCode)){
            throw new VisiableException("亲，验证码错误");
        }

        //进行注册
        UserInfo userInfo = new UserInfo();
        userInfo.setPhone(phone);
        userInfo.setNickname(nickname);
        userInfo.setPassword(password);
        userInfo.setLevel(1);
        userInfo.setHeadImgUrl("/images/default.jpg");
        userInfo.setState(UserInfo.STATE_NORMAL);
        userInfoMapper.insert(userInfo);
    }

    public void sendVerifyCode(String phone) {
        //假装已经进行手机号码校验
        //判断手机号是否唯一
        if(this.checkPhone(phone)){
            throw new VisiableException("该手机号已经被注册");
        }
         //1、生成4位验证码
        String verifyCode = UUID.randomUUID().toString().substring(0, 4);

        //2、发送到用户手机
        StringBuilder stringBuilder = new StringBuilder(80);
        String content = stringBuilder.append("您的手机验证码是：").append(verifyCode).append("请在").append(Cons.VERIFY_CODE_TIME).append("分钟之内使用").toString();
       try {
            sendMsg(phone,content);
        } catch (Exception e) {
            e.printStackTrace();
            throw new VisiableException(e.getMessage());
        }

        //3、缓存
        verifyCodeRedisService.setVerifyCode(phone,verifyCode);
    }
    @Value("${msg.url}")
    private String msgUrl;
    @Value("${msg.key}")
    private String msgKey;
    @Value("${msg.uid}")
    private String msgUid;

    private void sendMsg(String phone, String content) throws Exception {
        //请求路径
        URL url = new URL(msgUrl);

        //建立连接
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        //设置请求方法
        connection.setRequestMethod("GET");
        //设置请求参数
        StringBuilder stringBuilder = new StringBuilder(100);
        stringBuilder.append("Uid=").append(msgUid).append("&Key=")
                .append(msgKey).append("&smsMob=").append(phone)
                .append("&smsText=").append("【网建】"+content);
        //默认是false，设置true表示输出参数，表示将stringBuilder拼接上url进行请求发送
        connection.setDoOutput(true);
        connection.getOutputStream().write(stringBuilder.toString().getBytes("UTF-8"));

        //请求连接
        connection.connect();
        //获取响应数据
        String resp = StreamUtils.copyToString(connection.getInputStream(), Charset.forName("UTF-8"));
        int res= Integer.valueOf(resp);
        if(res<=0){
            throw new VisiableException("短信发送失败");
        }
    }

    public String userLogin(String username, String password) {
        //判断账号和密码
        UserInfo userInfo = userInfoMapper.selectByUsernameAndPassword(username, password);
         if(userInfo == null){
             throw new VisiableException("您的账号或者密码错误");
         }
        return createToken(userInfo);
    }

    private String createToken(UserInfo userInfo) {
        //缓存登录信息
        //缓存到redis
        //key：用户登录前缀+token，一个随机的uuid值
        //value：userInfo
        String token = UUID.randomUUID().toString().replace("-", "");
        //添加到redis中
        userInfoRedisService.addToken(UserInfoKeyPrefix.USER_INFO_TOKEN,token,userInfo);
        return token;
    }

    public List<UserInfo> list() {
        return userInfoMapper.selectAll();
    }

}
